
#pragma comment(lib, "openGL32.lib")  
#pragma comment(lib, "glu32.lib")  
#pragma comment(lib, "glaux.lib") 

#include <fstream>
#include <gl/glut.h>
#include <gl/glaux.h>
#include <stdlib.h>
#include <windows.h>    
#include <stdio.h>
#include<iostream>
#include <fstream>
#include <sstream>
using namespace std;

static int mode=0;
static int layer=0;
#define FileName "VideoTest"

static GLint  WindowWidth=600;
static GLint  WindowHeight=600;

static int frames;
static int shift;
static int shift_num;

static int shift_x=0;
static int shift_y=0;
static int t=0;
static int fresh=60;
static double light=1;

double ***F[3];
double ***G[3];
double ***H[3];


void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_POINTS);
	int i,j;
	for(i=0;i<WindowWidth ; i++)
	{	
		for(j=0; j<WindowHeight;j++)
		{
			double pixel_x=i/(WindowWidth/2.0)-1;
			double pixel_y=j/(WindowHeight/2.0)-1;

			double f=0,g=0,h=0;
			double red=0,green=0,blue=0;
			if((shift_x+i>0&&shift_x+i<WindowWidth)&&(shift_y+j>0&&shift_y+j<WindowHeight))
			{
				if(mode==0){
					for(int k=0;k<frames;k++){

						f=F[0][k][i][j];g=G[0][k][i+shift_x/2][j+shift_y/2];h=H[0][k][i+shift_x][j+shift_y];
						red+=f*g*h;									   							 	   

						f=F[1][k][i][j];g=G[1][k][i+shift_x/2][j+shift_y/2];h=H[1][k][i+shift_x][j+shift_y];
						green+=f*g*h;								   							 	   

						f=F[2][k][i][j];g=G[2][k][i+shift_x/2][j+shift_y/2];h=H[2][k][i+shift_x][j+shift_y];
						blue+=f*g*h;
					}
					//red/=frames;
					//green/=frames;
					//blue/=frames;

				}
				if(mode==1){
					
					f=F[0][t][i][j];g=G[0][t][i+shift_x/2][j+shift_y/2];h=H[0][t][i+shift_x][j+shift_y];
					f*=light;g*=light;h*=light;

					if(layer==0)red=f*g*h;								   							 	   
					if(layer==1)red=f;
					if(layer==2)red=g;	
					if(layer==3)red=h;		
	

					f=F[1][t][i][j];g=G[1][t][i+shift_x/2][j+shift_y/2];h=H[1][t][i+shift_x][j+shift_y];
					f*=light;g*=light;h*=light;

					if(layer==0)green=f*g*h;								   							 	   
					if(layer==1)green=f;
					if(layer==2)green=g;		
					if(layer==3)green=h;		
					   							 	   

					f=F[2][t][i][j];g=G[2][t][i+shift_x/2][j+shift_y/2];h=H[2][t][i+shift_x][j+shift_y];
					f*=light;g*=light;h*=light;

					if(layer==0)blue=f*g*h;								   							 	   
					if(layer==1)blue=f;
					if(layer==2)blue=g;		
					if(layer==3)blue=h;		
				}

			}
			glColor3f(red,green,blue);
			glVertex2f(pixel_x,pixel_y);
		}
	}
	glEnd();
	glutSwapBuffers();
}

void TimerFunction(int value)
{
	if(mode==1){
		t++;
		if(t>=frames)t=0;
		glutPostRedisplay();
	}
	glutTimerFunc(1000/fresh,TimerFunction,1);
	glutPostRedisplay();
}

void idle()
{
	if(mode==1){
		t++;
		if(t>=frames)t=0;
		glutPostRedisplay();
	}
}


void changeview(int key ,int x,int y)
{
	switch(key){
	case GLUT_KEY_UP:
		if(shift_y<shift*shift_num)
			shift_y+=shift;
		glutPostRedisplay();
		break;
	case GLUT_KEY_DOWN:
		if(shift_y>-shift*shift_num)
			shift_y-=shift;
		glutPostRedisplay();
		break;
	case GLUT_KEY_LEFT:
		if(shift_x<shift*shift_num)
			shift_x+=shift;
		glutPostRedisplay();
		break;
	case GLUT_KEY_RIGHT:
		if(shift_x>-shift*shift_num)
			shift_x-=shift;
		glutPostRedisplay();
		break;

	}
}


void changemode(unsigned char key,int x,int y){
	switch (key)
	{
	case 'c':
		if(mode==0)mode=1;
		else {
			mode=0;
			glutPostRedisplay();
		}
		break;
	case 'a':
		fresh++;
		cout<<fresh<<endl;
		break;
	case 's':
		fresh--;if(fresh<1)fresh=1;
		cout<<fresh<<endl;
		break;
	case 'n':
		light+=0.1;
		break;
	case 'm':
		light-=0.1;
		break;

	case 'r':
		layer=0;
		break;
	case 'f':
		layer=1;
		break;
	case 'g':
		layer=2;
		break;
	case 'h':
		layer=3;
		break;
	default:
		break;
	}
}


void init()
{
	cout<<"loading..."<<endl;
	fstream r;r.open (".\\data\\r.txt");
	fstream g;g.open (".\\data\\g.txt");
	fstream b;b.open (".\\data\\b.txt");
	r>>frames;
	r>>WindowWidth;r>>WindowHeight;
	r>>shift;r>>shift_num;
	light=pow(frames,1/3.0);
	for(int i=0;i<3;i++){
		F[i]=new double**[frames];
		G[i]=new double**[frames];
		H[i]=new double**[frames];
		for(int j=0;j<frames;j++){
			F[i][j]=new double* [WindowWidth];
			G[i][j]=new double* [WindowWidth];
			H[i][j]=new double* [WindowWidth];
			for(int k=0;k<WindowWidth;k++){
				F[i][j][k]=new double [WindowHeight];
				G[i][j][k]=new double [WindowHeight];
				H[i][j][k]=new double [WindowHeight];
			}
		}
	}

	for(int i=0;i<WindowHeight;i++){
		for(int j=0;j<WindowWidth;j++){
			for(int k=0;k<frames;k++){
				r>>F[0][k][j][i];r>>G[0][k][j][i];r>>H[0][k][j][i];
				g>>F[1][k][j][i];g>>G[1][k][j][i];g>>H[1][k][j][i];
				b>>F[2][k][j][i];b>>G[2][k][j][i];b>>H[2][k][j][i];
			}
		}		
	}

	cout<<"finish"<<endl;
}

int main(int argc, char* argv[])
{
	init();
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(WindowWidth, WindowHeight);
	glutCreateWindow(FileName);
	glutDisplayFunc(&display);
	//glutIdleFunc(&idle);
	glutSpecialFunc(changeview);
	glutKeyboardFunc(changemode);
	glutTimerFunc(1000/fresh,TimerFunction,1);
	glutMainLoop();
	return 0;
}


